package com.zjitc.servlet;

import com.zjitc.annotation.RequestMapping;
import com.zjitc.utils.Utils;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Create By IntelliJ IDEA
 *
 * @author: jsonor
 * @create-Time: 2017/10/30 15:48
 * @description: 截获访问tomcat中的所有请求，然后决定给哪个control中的方法进行调用
 */
@WebServlet(name = "dispatch", urlPatterns = {"/"}, loadOnStartup = 3)
public class DispatchServlet extends HttpServlet{

  /**
   * 每一个url对应一个method
   */
  private Map<String, Method> methodMap;
  /**
   * 每个方法名对应一个类描述
   */
  private Map<String, Class> classMap;

  @Override
  public void init() throws ServletException {
    methodMap = new HashMap<String, Method>(10);
    classMap = new HashMap<String, Class>(10);
    try {
      List<Class> clz = Utils.getAllClassFromPackage("com.zjitc.control");

      for (Class c : clz) {
        Method[] methods = c.getMethods();
        for (Method m : methods) {
          RequestMapping annotation = m.getAnnotation(RequestMapping.class);
          if (annotation != null) {
            classMap.put(m.getName(), c);
            methodMap.put(annotation.url(), m);
          }
        }
      }
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    }
  }

  @Override
  protected void service(HttpServletRequest req, HttpServletResponse resp)
      throws ServletException, IOException {

    // 获取用户需要访问的url
    // localhost:8080访问没有问题
    // http://192.170.179.179:8080/
    // 不能带参数
    String url = req.getRequestURL().substring(21);

    Method m = methodMap.get(url);
    Class c = classMap.get(m.getName());

    try {
      Object o = c.newInstance();
      m.invoke(o, req, resp);
    } catch (InstantiationException e) {
      e.printStackTrace();
    } catch (IllegalAccessException e) {
      e.printStackTrace();
    } catch (InvocationTargetException e) {
      e.printStackTrace();
    }
  }
}
